/*
 * main.cpp
 *
 *  Created on: 19/04/2012
 *      Author: alex
 */

#include "application/Floor.h"

using namespace std;
#include <iostream>
#include <string.h>
#include <list>
#include <signal.h>
#include <assert.h>
#include <sys/wait.h>

#include "IPC/EventHandler.h"
#include "IPC/SignalHandler.h"
#include "IPC/NamedPipe.h"
#include "IPC/AnonymousPipe.h"
#include "application/Floor.h"
#include "common/Argv.h"
#include "common/StringUtils.h"

class SIGINT_Handler : public EventHandler
{
    private:
        Floor *m_floor;
    public:

        SIGINT_Handler (): m_floor(NULL)
        {
        }

        virtual int handleSignal ( int signum )
        {
            assert ( signum == SIGINT );

            if(m_floor)
                m_floor->stopSimulation();

            return 0;
        }

        void setFloor(Floor *floor)
        {
            m_floor = floor;
        }

};

class SIGUSR1_Handler : public EventHandler
{
    private:
        Floor *m_floor;
    public:

        SIGUSR1_Handler (): m_floor(NULL)
        {
        }

        virtual int handleSignal ( int signum )
        {
            assert ( signum == SIGUSR1 );

            if(m_floor)
                m_floor->stopGeneratingPassengers();

            return 0;
        }

        void setFloor(Floor *floor)
        {
            m_floor = floor;
        }

};

int main (int argc,char **argv)
{

	string aux;
	string pipePath;
	int floorId;
	int floorAmmount;
	std::string keyGeneratorPath;
	Floor *currentFloor;
	SIGINT_Handler sigintHandler;
	SIGUSR1_Handler sigusr1Handler;
	Argv arguments;

	arguments.setArgv(argv);

	pipePath = arguments.getArg(1);
	floorId = StringUtils::StringToNumber<int>(arguments.getArg(2));
	floorAmmount = StringUtils::StringToNumber<int>(arguments.getArg(3));
	keyGeneratorPath = arguments.getArg(4);

	CLogger::create("Floor "+arguments.getArg(2));
	CLogger::log("Floor started",LogLevelEnum::DEBUG);

	currentFloor = new Floor(pipePath, keyGeneratorPath, floorId, floorAmmount);

    sigintHandler.setFloor(currentFloor);
    sigusr1Handler.setFloor(currentFloor);

    //Registro los event handlers
    SignalHandler :: getInstance()->registerHandler ( SIGINT,&sigintHandler );
    SignalHandler :: getInstance()->registerHandler ( SIGUSR1,&sigusr1Handler );

    currentFloor->startSimulation();

    SignalHandler :: destroy();

    delete currentFloor;

    CLogger::log("Floor terminated",LogLevelEnum::DEBUG);

    CLogger::destroy();
}
